<?php
/*
 * Cuatroxl
 *
 * LICENSE
 *
 * This file is part of Cuatroxl ( http://code.google.com/p/cuatroxl/ ).
 *
 * Cuatroxl is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cuatroxl is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cuatroxl.  If not, see <http ://www.gnu.org/licenses/>.
 *
 *
 * @category   Cuatroxl
 * @package    Cuatroxl_Zf_Action_Helper
 * @autor      Jimmy Collazos <jimmy.collazos@gmail.com>
 * @license    http://www.gnu.org/licenses/gpl.html     GPLv3
 * @version    0.01
 */



/**
 * @see Zend_Controller_Plugin_Abstract
 */
require_once 'Zend/Controller/Plugin/Abstract.php';


/**
 * @category   Cuatroxl
 * @package    Cuatroxl_Controller
 * @subpackage Cuatroxl_Controller_Plugin
 * @license    http://www.gnu.org/licenses/gpl.html     GPLv3
 */
class Cuatroxl_Controller_Plugin_DataPage extends Zend_Controller_Plugin_Abstract
{

    /*
     * Variable de configuración
     *
     * @var Array
     */
    protected       $_config      = array('autoload'  => false
                            ,'filePath'     => 'public/:module/:controller/:action.xml'
                            ,'xpath'        => ''
                            ,'basePath'     => APPLICATION_PATH
                            // esta opción es solo para cuando NO usamos Zend_Application
                            ,'_keyPlugin'   => '');

    /*
     * Ruta del archivo XML a cargar
     *
     * @var string
     */
    protected       $_filePath = null;

    /*
     * Xpath query para poder obteenr el nodo por defecto del XML
     *
     * @var string
     */
    protected       $_xpath = null;

    

    /*
     * En esta variable se almacena el XML final con el que podemos trabajar
     * desde el controlador
     *
     * @var SimpleXMLElement
     */
    protected       $_data;


    /*
     * Nombre asignado en el archivo de configuración de al aplicación
     *
     * @var string
     */
    private         $_keyPlugin;

    /**
     * Constructor
     *
     * @param  Array
     * @return void
     */

    public function  __construct( array $options = array() ) {
        
        $this->_setConfig($options);
            
    }

    /*
     * routeShutdown() es como el constructor ya que se usa para setear el XML
     * en caso de estar activado el "autoload" y también setea la configuración del INI
     *
     * @param Zend_Controller_Request_Abstract
     * @return void
     */
    public function routeShutdown( Zend_Controller_Request_Abstract $request)
    {
        
        //@TODO cambiar esto por una funcion que setee todas las opciones
        $bootstrap = Zend_Controller_Front::getInstance()
                            ->getParam('bootstrap');
        if(! empty($bootstrap) ){
            $bootstrapOptions   = $bootstrap->getOptions();
            $this->_keyPlugin          = $this->_getKeyPlugin($bootstrapOptions['resources']['frontController']['plugins']);
            if($this->_keyPlugin){
                if(! empty($bootstrapOptions[$this->_keyPlugin]['config'])){
                    $this->_setConfig($bootstrapOptions[$this->_keyPlugin]['config']);
                }
            }
            //@TODO añadir una excepción
            $this->_parseFilePath();
            $this->_parseXPath();
            
            if( $this->_config['autoload'] ){
                $this->_loadXmlFile();
                $this->_setXPath();
            }
        }
    }

    /*
     * Setea los daots en la variable _data
     *
     * @param SimpleXMLElement
     * @return void
     */
    public function setData ( SimpleXMLElement $data )
    {
        $this->_data = $data;

        if(!empty ($this->_keyPlugin) ){
            Zend_Controller_Front::getInstance()
                    ->setParam($this->_keyPlugin, $this->_data);
        }
    }

    /*
     * Devueble el XML obtenido
     *
     * @return Cuatroxl_Controller_Plugin_DataPage $_data
     * 
     */
    public function getData ()
    {
        return $this->_data;
    }

    /*
     * Configura todas las opiones de la clase
     * 
     * @var array
     * @return Cuatroxl_Controller_Plugin_DataPage  Provides a fluent interface
     *
     */
    protected function _setConfig( array $config) {
        foreach ($config as $k => $v){
            if(!empty ($v)){
                $this->_config[$k] = $v;
            }
        }
        return $this;
    }

    /*
     * Carga el archivo XML
     *
     * @var string
     * @return Cuatroxl_Controller_Plugin_DataPage Provides a fluent interface
     *
     */
    protected function _loadXmlFile( string $fileName = NULL ) {
        if( $fileName === NULL ){
            $fileName = $this->_filePath;
        }
        if( file_exists( $fileName ) ){
            $data   = simplexml_load_file( $fileName );
            $this->setData( $data );
        }
        return $this;
    }

    /*
     * Ejecuta una query sobre el XML con xpath y devuelve TRUE o FALSE  según el exito de la consulta
     *
     * @var string
     * @return Boolean
     *
     */
    protected function _setXPath( string $path = NULL ) {
        if( $path === NULL){
            $path = $this->_xpath;
        }

        if( empty($this->_xpath) ){
            return false;
        }

        $data = $this->_data->xpath($this->_xpath);

        if( empty ($data[0]) ){
            return false;
        }else{
            $this->setData( array_shift( $data ) );
            return true;
        }

        
    }

    /*
     * remplaza los comodines en la ruta al XML y devuelve TRUE o FALSE
     * según el exito de la consulta
     *
     * @return Boolean
     *
     */
    private function _parseFilePath() {
        
        //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route
        if(! preg_match_all("/:[^\/\.]+/s", $this->_config['filePath'], $matches) ){
            return false;
        }
        $request        = $this->getRequest();
        $values         = array();
        $matches        = $matches[0];
        foreach($matches as $v){
            $values[] = $request->getParam(substr($v, 1));
        }
        $matches[]          = '/';
        $values[]           = DIRECTORY_SEPARATOR;
        $this->_filePath    = str_replace($matches, $values, $this->_config['basePath'].$this->_config['filePath']);
        
        return true;
    }

    /*
     * remplaza los comodines en la ruta al nodop por defecto del  XML
     * y devuelve TRUE o FALSE  según el exito de la consulta
     *
     * @return Boolean
     *
     */
    private function _parseXPath() {

        //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route
        if( empty ($this->_config['xpath']) ){
            return false;
        }
        if(! preg_match_all("/:[\d\w_]+/s", $this->_config['xpath'], $matches) ){
            $this->_xpath = $this->_config['xpath'];
            return true;
        }
        $request        = $this->getRequest();
        $values         = array();
        $matches        = $matches[0];
        foreach($matches as $v){
            $values[] = $request->getParam(substr($v, 1));
        }
        
        $this->_xpath    = str_replace($matches, $values, $this->_config['xpath']);

        return true;
    }


    /*
     * Devuelve el nombre que se designó en el archivo de configuración
     *
     * @return string o false
     */
    private function _getKeyPlugin(array $config)
    {
        foreach ($config as $k => $v){
            if($v === 'Cuatroxl_Controller_Plugin_DataPage'){
                return $k;
            }
        }
        return false;
    }
}